package com.run.runbbs.service.impl;

import com.run.runbbs.entity.User;
import com.run.runbbs.util.Constant;
import com.run.runbbs.util.RedisKeyUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.SessionCallback;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class FollowService implements Constant {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private UserService userService;
    //关注 entityType: 用户=3
    public void follow(int userId,int entityType,int entityId){
        redisTemplate.execute(new SessionCallback() {
            @Override
            public Object execute(RedisOperations redisOperations) throws DataAccessException {
                String followeeKey= RedisKeyUtil.getFolloweeKey(userId, entityType);//关注
                String followerKey=RedisKeyUtil.getFollowerKey(entityType, entityId);//粉丝
                redisOperations.multi();
                // add(K key, V value, double score);score表示一个分数，所有的排序都是基于这个score。
                redisOperations.opsForZSet().add(followeeKey,entityId,System.currentTimeMillis());
                redisOperations.opsForZSet().add(followerKey,userId,System.currentTimeMillis());
                return redisOperations.exec();
            }
        });
    }

    //取消关注
    public void unfollow(int userId,int entityType,int entityId){
        redisTemplate.execute(new SessionCallback() {
            @Override
            public Object execute(RedisOperations redisOperations) throws DataAccessException {
                String followeeKey= RedisKeyUtil.getFolloweeKey(userId, entityType);//关注
                String followerKey=RedisKeyUtil.getFollowerKey(entityType, entityId);//粉丝
                redisOperations.multi();
                redisOperations.opsForZSet().remove(followeeKey,entityId);
                redisOperations.opsForZSet().remove(followerKey,userId);
                return redisOperations.exec();
            }
        });
    }

    //查询关注的实体的数量
    public long findFolloweeCount(int userId, int entityType){
        String followeeKey= RedisKeyUtil.getFolloweeKey(userId,entityType);
        //zCard()：统计数量
        return redisTemplate.opsForZSet().zCard(followeeKey);
    }
    //查询实体的粉丝数量
    public long findFollowerCount(int entityType,int entityId){
        String followerKey =RedisKeyUtil.getFollowerKey(entityType, entityId);
        return redisTemplate.opsForZSet().zCard(followerKey);
    }
    //查询当前用户是否已经关注该实体
    public boolean hasFollowed(int userId,int entityType,int entityId){
        String followeeKey=RedisKeyUtil.getFolloweeKey(userId, entityType);
        return redisTemplate.opsForZSet().score(followeeKey,entityId)!=null;
    }

    //查询某用户关注的人
    public List<User> findFollowees(int userId,int offset,int limit){
        String followeeKey=RedisKeyUtil.getFolloweeKey(userId,ENTITY_TYPE_USER);
        Set<Integer> targetIds=redisTemplate.opsForZSet().reverseRange(followeeKey,offset,offset+limit-1);
        if(targetIds==null){
            return  null;
        }
        List<User> list=new ArrayList<>();
        for(Integer targetId:targetIds){
            User user=userService.findSimpleUserById(targetId);
            list.add(user);
        }
        return  list;
    }
    //查询某个用户的粉丝
    public List<User> findFollowers(int userId,int offset,int limit){
        String followerKey=RedisKeyUtil.getFollowerKey(ENTITY_TYPE_USER,userId);
        Set<Integer> targetIds=redisTemplate.opsForZSet().reverseRange(followerKey,offset,offset+limit-1);
        if(targetIds==null){
            return  null;
        }
        List<User> list=new ArrayList<>();
        for(Integer targetId:targetIds){
            User user=userService.findSimpleUserById(targetId);
            list.add(user);
        }
        return  list;
    }
}
